import axios from 'axios'
import router from '@/router'

const API_URL = process.env.VUE_APP_API_URL || 'http://localhost:3000/api'

// 安全地从localStorage获取用户数据
const getSafeUserFromStorage = () => {
  try {
    const userJson = localStorage.getItem('user');
    if (!userJson) return null;
    
    const user = JSON.parse(userJson);
    // 验证用户对象必须包含id和username字段
    if (!user || !user.id || !user.username) {
      console.error('localStorage中的用户数据不完整，重置用户状态');
      localStorage.removeItem('user');
      return null;
    }
    return user;
  } catch (error) {
    console.error('从localStorage解析用户数据失败:', error);
    localStorage.removeItem('user');
    return null;
  }
};

// 安全地从localStorage获取token
const getSafeTokenFromStorage = () => {
  const token = localStorage.getItem('token');
  if (!token || typeof token !== 'string' || token.trim() === '') {
    if (token) {
      console.error('localStorage中的token无效，已清除');
      localStorage.removeItem('token');
    }
    return '';
  }
  return token;
};

const state = {
  token: getSafeTokenFromStorage(),
  user: getSafeUserFromStorage()
}

const mutations = {
  AUTH_SUCCESS(state, { token, user }) {
    state.token = token
    state.user = user
  },
  AUTH_ERROR(state) {
    state.token = ''
    state.user = null
  },
  LOGOUT(state) {
    state.token = ''
    state.user = null
  },
  UPDATE_USER(state, user) {
    state.user = user
  }
}

const actions = {
  // 注册用户
  async register({ commit, dispatch }, userData) {
    try {
      dispatch('setLoading', true, { root: true })
      const response = await axios.post(`${API_URL}/auth/register`, userData)
      const token = response.data.token
      
      // 确保token已设置到本地存储
      localStorage.setItem('token', token)
      
      // 获取用户信息
      await dispatch('getUserData', token)
      
      return true
    } catch (error) {
      commit('AUTH_ERROR')
      const errorMessage = error.response ? error.response.data.message : error.message
      dispatch('setError', errorMessage, { root: true })
      return false
    } finally {
      dispatch('setLoading', false, { root: true })
    }
  },
  
  // 登录用户
  async login({ commit, dispatch }, credentials) {
    try {
      dispatch('setLoading', true, { root: true })
      console.log('开始登录请求...')
      const response = await axios.post(`${API_URL}/auth/login`, credentials)
      console.log('登录响应:', response.data)
      const token = response.data.token
      
      if (!token) {
        console.error('服务器未返回令牌')
        throw new Error('登录失败：服务器未返回有效令牌')
      }
      
      // 立即存储token到本地存储并删除旧令牌
      localStorage.removeItem('token')
      localStorage.removeItem('user')
      localStorage.setItem('token', token)
      
      // 验证token已成功保存
      const savedToken = localStorage.getItem('token')
      console.log('保存的令牌有效:', !!savedToken)
      console.log('保存的令牌值前10个字符:', savedToken?.substring(0, 10))
      
      // 使用新token更新状态
      commit('AUTH_SUCCESS', { token, user: null })
      
      // 获取用户信息
      try {
        const user = await dispatch('getUserData', token)
        console.log('用户数据已获取和保存', user)
        
        // 如果有重定向参数，登录后跳转
        const redirectPath = router.currentRoute.value.query.redirect
        if (redirectPath) {
          router.push(redirectPath)
        }
        
        return true
      } catch (userError) {
        console.error('获取用户数据失败:', userError)
        // 尝试使用备用方法获取用户数据
        const fallbackUser = await dispatch('getUserDataFallback', token)
        console.log('使用备用方法获取用户数据成功', fallbackUser)
        
        // 如果有重定向参数，登录后跳转
        const redirectPath = router.currentRoute.value.query.redirect
        if (redirectPath) {
          router.push(redirectPath)
        }
        
        return true
      }
    } catch (error) {
      console.error('登录失败:', error)
      commit('AUTH_ERROR')
      localStorage.removeItem('token')
      localStorage.removeItem('user')
      
      const errorMessage = error.response ? error.response.data.message : error.message
      dispatch('setError', errorMessage, { root: true })
      return false
    } finally {
      dispatch('setLoading', false, { root: true })
    }
  },
  
  // 获取用户数据
  async getUserData({ commit }, token) {
    try {
      console.log('正在获取用户数据...');
      // 确保我们有有效的令牌
      if (!token) {
        console.error('令牌无效，无法获取用户数据');
        throw new Error('无效的认证令牌');
      }
      
      // 同时使用两种格式的认证头
      const config = { 
        headers: { 
          'Authorization': `Bearer ${token}`,
          'x-auth-token': token 
        } 
      };
      
      console.log('使用的认证头:', {
        authHeader: `Bearer ${token.substring(0, 10)}...`,
        tokenHeader: `${token.substring(0, 10)}...`,
        tokenLength: token.length
      });
      
      const response = await axios.get(`${API_URL}/auth/user`, config);
      console.log('获取到的用户数据:', response.data);
      
      // 确保我们收到有效的用户数据
      if (!response.data || typeof response.data !== 'object') {
        console.error('服务器返回的用户数据无效:', response.data);
        throw new Error('服务器返回的用户数据无效');
      }
      
      const user = response.data;
      
      // 额外检查用户对象是否包含必要字段
      if (!user.id || !user.username) {
        console.error('用户数据缺少必要字段:', user);
        throw new Error('用户数据格式不完整');
      }
      
      // 存储token和用户信息
      localStorage.setItem('token', token);
      localStorage.setItem('user', JSON.stringify(user));
      
      // 标记认证成功
      commit('AUTH_SUCCESS', { token, user });
      
      // 返回用户信息
      return user;
    } catch (error) {
      console.error('获取用户数据失败:', error.message);
      // 如果遇到401或403错误，说明令牌可能无效
      if (error.response && (error.response.status === 401 || error.response.status === 403)) {
        console.error('认证失败，可能是令牌已过期');
        // 清除无效令牌
        localStorage.removeItem('token');
        localStorage.removeItem('user');
        commit('AUTH_ERROR');
      }
      throw error;
    }
  },
  
  // 获取用户数据的备用方法
  async getUserDataFallback({ commit }, token) {
    try {
      console.log('使用备用方法获取用户数据...');
      // 确保令牌有效
      if (!token || typeof token !== 'string' || token.trim() === '') {
        throw new Error('无效的令牌');
      }
      
      // 尝试直接从JWT解析用户信息
      const parts = token.split('.');
      if (parts.length !== 3) {
        throw new Error('无效的JWT令牌格式：令牌应包含三个部分');
      }
      
      const base64Url = parts[1];
      if (!base64Url) {
        throw new Error('无效的JWT令牌格式：无法提取数据部分');
      }
      
      let jsonPayload;
      try {
        const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
        jsonPayload = decodeURIComponent(
          window.atob(base64)
            .split('')
            .map(function(c) {
              return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
            })
            .join('')
        );
      } catch (decodeError) {
        console.error('JWT解码失败:', decodeError);
        throw new Error('JWT解码失败: ' + decodeError.message);
      }
      
      let payload;
      try {
        payload = JSON.parse(jsonPayload);
      } catch (parseError) {
        console.error('JWT载荷解析失败:', parseError);
        throw new Error('JWT载荷解析失败: ' + parseError.message);
      }
      
      console.log('从JWT解析的用户数据:', payload);
      
      if (!payload || !payload.user) {
        throw new Error('JWT令牌中没有用户数据');
      }
      
      const user = payload.user;
      
      // 确保用户数据包含必要字段
      if (!user.id || !user.username) {
        console.error('JWT中的用户数据缺少必要字段');
        throw new Error('无效的用户数据');
      }
      
      // 存储token和用户信息
      localStorage.setItem('token', token);
      localStorage.setItem('user', JSON.stringify(user));
      
      commit('AUTH_SUCCESS', { token, user });
      return user;
    } catch (error) {
      console.error('备用方法获取用户数据失败:', error.message);
      commit('AUTH_ERROR');
      localStorage.removeItem('token');
      localStorage.removeItem('user');
      throw error;
    }
  },
  
  // 登出用户
  logout({ commit }) {
    commit('LOGOUT')
    localStorage.removeItem('token')
    localStorage.removeItem('user')
    router.push('/')
  },
  
  // 更新用户信息
  async updateProfile({ commit, state, dispatch }, userData) {
    try {
      dispatch('setLoading', true, { root: true })
      const token = state.token
      const config = { 
        headers: { 
          'Authorization': `Bearer ${token}`,
          'x-auth-token': token 
        } 
      }
      const response = await axios.put(`${API_URL}/users/profile`, userData, config)
      
      const updatedUser = response.data
      localStorage.setItem('user', JSON.stringify(updatedUser))
      commit('UPDATE_USER', updatedUser)
      
      return true
    } catch (error) {
      const errorMessage = error.response ? error.response.data.message : error.message
      dispatch('setError', errorMessage, { root: true })
      return false
    } finally {
      dispatch('setLoading', false, { root: true })
    }
  },
  
  // 更改密码
  async changePassword({ state, dispatch }, passwordData) {
    try {
      dispatch('setLoading', true, { root: true })
      const token = state.token
      const config = { 
        headers: { 
          'Authorization': `Bearer ${token}`,
          'x-auth-token': token 
        } 
      }
      await axios.put(`${API_URL}/users/password`, passwordData, config)
      return true
    } catch (error) {
      const errorMessage = error.response ? error.response.data.message : error.message
      dispatch('setError', errorMessage, { root: true })
      return false
    } finally {
      dispatch('setLoading', false, { root: true })
    }
  },
  
  // 刷新认证状态
  async refreshAuthState({ commit, dispatch }) {
    try {
      console.log('刷新认证状态...')
      // 检查本地存储的令牌
      const token = localStorage.getItem('token')
      if (!token) {
        console.log('本地不存在令牌，认证状态为：未登录')
        commit('AUTH_ERROR')
        return false
      }
      
      console.log('本地存在令牌，尝试获取用户数据')
      try {
        // 尝试获取用户数据来验证令牌有效性
        const user = await dispatch('getUserData', token)
        console.log('令牌有效，用户已刷新:', user.username)
        return true
      } catch (error) {
        console.error('令牌可能已过期，尝试备用方法:', error.message)
        try {
          // 尝试备用方法
          const fallbackUser = await dispatch('getUserDataFallback', token)
          console.log('使用备用方法验证成功:', fallbackUser.username)
          return true
        } catch (fallbackError) {
          // 如果两种方法都失败，说明令牌无效
          console.error('认证刷新失败，令牌无效:', fallbackError.message)
          commit('AUTH_ERROR')
          localStorage.removeItem('token')
          localStorage.removeItem('user')
          return false
        }
      }
    } catch (error) {
      console.error('刷新认证状态时出错:', error)
      commit('AUTH_ERROR')
      return false
    }
  }
}

const getters = {
  isAuthenticated: state => !!state.token,
  isAdmin: state => state.user && (state.user.is_admin === true || state.user.is_admin === 1),
  currentUser: state => state.user,
  token: state => state.token
}

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters
} 